package com.yunzai.onebot.websocket;

import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import org.java_websocket.client.WebSocketClient;
import org.java_websocket.handshake.ServerHandshake;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.net.URI;
import java.net.URISyntaxException;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.util.Collections;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;

public class OneBotClient extends WebSocketClient {

    private static final Logger log = LoggerFactory.getLogger(OneBotClient.class);
    private boolean isClosed = false;
    private final Gson gson = new Gson();

    // 使用线程安全的 Map 存储所有客户端 Session
    private static final ConcurrentHashMap<Long, List<JsonObject>> userMessageList = new ConcurrentHashMap<>();

    private String bot;

    public OneBotClient(String serverUri, String bot) throws URISyntaxException {
        super(new URI(serverUri));
        this.bot = bot;
    }

    @Override
    public void onOpen(ServerHandshake handshake) {
        log.info("已连接OneBot服务器");
    }

    /**
     * yunzai接口响应，防止连接断开
     * @param json
     */
    private void result(JsonObject json){
        JsonObject result = new JsonObject();
        result.addProperty("echo", json.get("echo").getAsString());
        result.addProperty("retcode", 1);
        result.addProperty("status", "success");
        result.add("error", null);

        String action = json.get("action").getAsString();
        JsonObject data = new JsonObject();
        if("_set_model_show".equals(action)) {
            data = json.get("params").getAsJsonObject();
        } else if("get_login_info".equals(action)) {
            data.addProperty("user_id", bot);
            data.addProperty("nickname", "流萤");
        } else if("get_guild_service_profile".equals(action)) {

        } else if("get_online_clients".equals(action)) {
            result.add("clients", data);
            data.add("clients", new JsonObject());
        } else if("get_version_info".equals(action)) {
            data.addProperty("app_name", "YunzaiWeb");
            data.addProperty("app_version", "1.0.0");
        } else if("get_cookies".equals(action)) {
            JsonObject params = new JsonObject();
            params.addProperty("domain", "qun.qq.com");
            data.add("data", params);
        } else if("get_friend_list".equals(action)) {
            data.add("data", new JsonArray());
        } else if("get_group_list".equals(action)) {
            data.add("data", new JsonArray());
        } else if("get_guild_list".equals(action)) {
            data.add("data", new JsonArray());
        } else if("get_guild_service_list".equals(action)) {
            data.add("data", new JsonArray());
        }
        result.add("data", data);
        send(result.toString());
    }

    /**
     * 响应消息保存
     * @param userId
     * @param message
     */
    public void addUserMessageList(Long userId, JsonObject message){
        userMessageList.compute(userId, (key, list) -> {
            if (list == null) {
                list = new CopyOnWriteArrayList<>();
            }
            ((CopyOnWriteArrayList<JsonObject>) list).addIfAbsent(message);
            return list; // 返回修改后的列表
        });
    }

    @Override
    public void onMessage(String message) {
        JsonObject json = gson.fromJson(message, JsonObject.class);

        result(json);

        fileMsg(json);

        // 检查是否是响应消息
        if (json.has("params")) {
            JsonObject params = json.get("params").getAsJsonObject();
            if (params.has("user_id")) {
                Long userId = params.get("user_id").getAsLong();
                addUserMessageList(userId, json);
            }
        }
    }

    /**
     * 文件消息解析
     * @param response
     */
    private void fileMsg(JsonObject response) {
        JsonObject params = response.getAsJsonObject("params");
        JsonArray messages = params.getAsJsonArray("messages");
        if (messages == null) {
            messages = params.getAsJsonArray("message");
            params.remove("messages");
        }
        if(messages != null) uinMsg(params, messages);
    }

    /**
     * 匿名消息解析
     * @param params
     * @param messages
     */
    private void uinMsg(JsonObject params, JsonArray messages) {
        JsonArray msg = new JsonArray();
        messages.forEach(i -> {
            JsonObject asJsonObject = i.getAsJsonObject();
            if ("node".equals(asJsonObject.get("type").getAsString())) {
                JsonObject data = asJsonObject.getAsJsonObject("data");
                JsonArray content = data.getAsJsonArray("content");
                content.forEach(j -> {
                    msg.add(j.getAsJsonObject());
                });
            }
        });
        if(!msg.isEmpty()) params.add("message", msg);
    }

    @Override
    public void onMessage(ByteBuffer bytes) {
        onMessage(new String(bytes.array(), StandardCharsets.UTF_8));
        super.onMessage(bytes);
    }

    @Override
    public void onClose(int code, String reason, boolean remote) {
        log.info("已断开OneBot服务器: {}", reason);
        isClosed = true;
    }

    @Override
    public void onError(Exception ex) {
        log.error(ex.getMessage());
    }

    @Override
    public boolean isClosed() {
        return isClosed;
    }

    // 发送消息并添加回调
    public void sendMessage(JsonObject message) {
        String msgId = UUID.randomUUID().toString();
        message.addProperty("message_id", msgId);
        message.addProperty("timestamp", System.currentTimeMillis());
        message.addProperty("self_id", bot);
        send(message.toString());
    }

    public List<JsonObject> getNewMessage(Long userId) {
        // 原子性地移除并返回列表
        List<JsonObject> messages = userMessageList.remove(userId);
        return messages != null ? messages : Collections.emptyList();
    }
}
